home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Tool Chest / Dev.CD Feb 97 TC.toast / Sample Code / Development Tools & Languages / AppsToGo / DTS.Lib / AEUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  9.0 KB  |  339 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         DTS.Lib
  5. ** File:         AEUtils.c
  6. ** Written by:   Keith Rollin
  7. ** Modified by:  Eric Soldan
  8. **
  9. ** Copyright © 1990-1991 Apple Computer, Inc.
  10. ** All rights reserved.
  11. */
  12.  
  13. /* You may incorporate this sample code into your applications without
  14. ** restriction, though the sample code has been provided "AS IS" and the
  15. ** responsibility for its operation is 100% yours.  However, what you are
  16. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  17. ** after having made changes. If you're going to re-distribute the source,
  18. ** we require that you make it clear in the source that the code was
  19. ** descended from Apple Sample Code, but that you've made changes. */
  20.  
  21.  
  22.  
  23. /*****************************************************************************/
  24.  
  25.  
  26.  
  27. #include "DTS.Lib2.h"
  28. #include "DTS.Lib.protos.h"
  29.  
  30. #ifndef __NOTIFICATION__
  31. #include <Notification.h>
  32. #endif
  33.  
  34. #ifndef __RESOURCES__
  35. #include <Resources.h>
  36. #endif
  37.  
  38. #ifndef __EPPC__
  39. #include <EPPC.h>
  40. #endif
  41.  
  42.  
  43.  
  44. /*****************************************************************************/
  45.  
  46.  
  47.  
  48. extern Boolean        gHasPPCToolbox;
  49.  
  50. Boolean                gNotifyUser   = true;
  51. static Boolean        gNotifyActive = false;
  52. static NMRec        gNotifyUserInfo = {
  53.     nil,        /* qLink */
  54.     nmType,        /* qType */
  55.     0,            /* nmFlags */
  56.     0L,            /* nmPrivate */
  57.     0,            /* nmReserved */
  58.     1,            /* nmMark */
  59.     nil,        /* nmIcon */
  60.     (Handle)-1,    /* nmSound */
  61.     nil,        /* nmStr */
  62.     nil,        /* nmResp */
  63.     0L            /* nmRefCon */
  64. };
  65.  
  66.  
  67.  
  68. /*****************************************************************************/
  69. /*****************************************************************************/
  70.  
  71. #ifdef applec
  72. #pragma segment ATGAppleEvents
  73. #endif
  74.  
  75. /*****************************************************************************/
  76. /*****************************************************************************/
  77.  
  78.  
  79.  
  80. /* Simply calls AEProcessAppleEvent and reports any errors.
  81. ** AEProcessAppleEvent looks in its table of registered events and sees if
  82. ** the current event is registered.  If so, off we go. */
  83.  
  84. void    DoHighLevelEvent(EventRecord *event)
  85. {
  86.     OSErr    err;
  87.  
  88.     err = AEProcessAppleEvent(event);
  89. }
  90.  
  91.  
  92.  
  93. /*****************************************************************************/
  94.  
  95.  
  96.  
  97. /* This function returns the zone, machine, and application name for the
  98. ** indicated target descriptor. */
  99.  
  100. OSErr    GetTargetInfo(AEAddressDesc targetDesc, StringPtr zone,
  101.                       StringPtr machine, StringPtr application)
  102. {
  103.     ProcessSerialNumber targetPSN;
  104.     PortInfoRec            portInfo;
  105.     TargetID            theTargetID;
  106.     OSErr                err;
  107.  
  108.     zone[0]        = 0;
  109.     machine[0]     = 0;
  110.     application[0] = 0;
  111.     err = noErr;
  112.  
  113.     if (targetDesc.descriptorType == typeProcessSerialNumber) {
  114.         targetPSN = **(ProcessSerialNumber **)(targetDesc.dataHandle);
  115.         err = GetPortNameFromProcessSerialNumber(&portInfo.name, &targetPSN);
  116.         if (!err)
  117.             pcpy(application, portInfo.name.name);
  118.         return(err);
  119.     }
  120.  
  121.     if (targetDesc.descriptorType == typeTargetID) {
  122.         theTargetID = **(TargetID **)(targetDesc.dataHandle);
  123.         switch (theTargetID.location.locationKindSelector) {
  124.             case ppcNoLocation:
  125.                 break;
  126.             case ppcNBPLocation:
  127.                 pcpy(zone,    theTargetID.location.u.nbpEntity.zoneStr);
  128.                 pcpy(machine, theTargetID.location.u.nbpEntity.objStr);
  129.                 break;
  130.             case ppcNBPTypeLocation:
  131.                 break;
  132.         }
  133.         pcpy(application, theTargetID.name.name);
  134.         return(noErr);
  135.     }
  136.  
  137.     return(errAEWrongDataType);
  138. }
  139.  
  140.  
  141.  
  142. /*****************************************************************************/
  143.  
  144.  
  145.  
  146. /* Creates a TargetID.
  147. **
  148. ** If sendDirect is TRUE, the target is specified by setting a
  149. ** ProcessSerialNumber to kCurrentProcess.  This has the advantage of sending
  150. ** the message directly to ourselves, bypassing ePPC and gaining about a 10-15x
  151. ** speed improvement.  If sendDirect is FALSE, we see if we have the
  152. ** PPCToolBox.  If not, then we are forced to do a direct send.  If we do have
  153. ** the PPCToolbox, then we call PPCBrowser.  We then look at the reply, and
  154. ** factor in the mode we are going to use in AESend.  If that mode is
  155. ** kAEWaitReply and the user selected us as the target, we have to turn that
  156. ** into a direct send.  This is because the AppleEvent Manager will otherwise
  157. ** post the event as a high-level event.  However, we are busy waiting for a
  158. ** reply, not looking for events, so we'll hang.  We avoid this by forcing a
  159. ** direct send. */
  160.  
  161. OSErr    MakeTarget(AEAddressDesc *target, Boolean sendDirect, short replyMode,
  162.                    Str255 prompt, Str255 applListLabel,
  163.                    PPCFilterUPP portFilter,
  164.                    char *theLocNBPType)
  165. {
  166.     OSErr                    err;
  167.     ProcessSerialNumber     targetPSN;
  168.     ProcessSerialNumber     myPSN;
  169.     TargetID                theTargetID;
  170.     Boolean                    sendingToSelf;
  171.  
  172.     static LocationNameRec    location;
  173.     static PortInfoRec        portInfo;
  174.     static Boolean            defaultOK = false;
  175.  
  176.     err = noErr;    /* Make sure we do the code for the second main if. */
  177.  
  178.     target->dataHandle = nil;
  179.         /* Assume we will fail and nil this descriptor out. */
  180.  
  181.     if (!sendDirect) {
  182.         if (!gHasPPCToolbox)
  183.             sendDirect = true;    /* No tools to send with, so send direct. */
  184.  
  185.         else {        /* We are not sending to self. */
  186.                     /* sendDirect is false.           */
  187.             err = PPCBrowser(
  188.                 prompt,            /* Browse dialog box prompt.           */
  189.                 applListLabel,    /* The 'programs' list title.           */
  190.                 defaultOK,        /* Initially false.                       */
  191.                 &location,        /* Correct if defaultOK is true.       */
  192.                 &portInfo,        /* Correct if defaultOK is true.       */
  193.                 portFilter,        /* Port filtering.                       */
  194.                 (StringPtr)theLocNBPType    /* List ports of this type */
  195.             );
  196.  
  197.             if (!err) {                    /* If user didn't cancel... */
  198.                 defaultOK = true;        /* Default to the same port next time. */
  199.                 if (replyMode == kAEWaitReply) {
  200.                     /* Sender wants a reply and will be waiting... */
  201.  
  202.                     sendingToSelf = false;
  203.                         /* Assume that we aren't sending to ourselves. */
  204.  
  205.                     if (!location.locationKindSelector) {
  206.                         /* Hey, we are sending to ourselves! */
  207.  
  208.                         err = GetProcessSerialNumberFromPortName(
  209.                                 &portInfo.name, &targetPSN);
  210.                         if (!err) {
  211.                             GetCurrentProcess(&myPSN);
  212.                             err = SameProcess(&targetPSN, &myPSN, &sendingToSelf);
  213.                         }
  214.                     }
  215.  
  216.                     if (sendingToSelf)
  217.                         sendDirect = true;
  218.  
  219.                 }
  220.             }
  221.         }
  222.     }
  223.  
  224.     if (!err) {
  225.         if (sendDirect) {
  226.             /* Finally, we get to the point... */
  227.  
  228.             targetPSN.highLongOfPSN = 0;
  229.             targetPSN.lowLongOfPSN = kCurrentProcess;
  230.                 /* Process serial # is equal to kCurrentProcess.  This
  231.                 ** bypasses ePPC and speeds up things considerably. */
  232.  
  233.             err = AECreateDesc(
  234.                 typeProcessSerialNumber,    /* Standard PSN descriptor type. */
  235.                 (Ptr)&targetPSN,            /* "No ePPC" process serial #.     */
  236.                 sizeof(targetPSN),            /* Size of data (2 longs).         */
  237.                 target                        /* Wherefore art thou desc.         */
  238.             );
  239.         }
  240.         else {
  241.             theTargetID.location = location;
  242.             theTargetID.name     = portInfo.name;
  243.                 /* The fields sessionID does not need to be filled in now.
  244.                 ** The sessionID is returned when you actually connect to
  245.                 ** a port.  You can then use the sessionID from that point
  246.                 ** on to improve speed.
  247.                 **
  248.                 ** You also don't need to fill in the recvrName field at this
  249.                 ** point.  This is filled in, again, when the session is
  250.                 ** actually established.
  251.                 **
  252.                 ** The amount of data for a non-us target is bigger.
  253.                 ** We need the whole dealie for our target, since
  254.                 ** it is out on the net somewhere. */
  255.  
  256.             err = AECreateDesc(
  257.                 typeTargetID,            /* Standard target descriptor type. */
  258.                 (Ptr)&theTargetID,        /* The data for the descriptor.        */
  259.                 sizeof(theTargetID),    /* Size of the data.                */
  260.                 target                    /* Wherefore art thou desc.            */
  261.             );
  262.         }
  263.     }
  264.     return (err);
  265. }
  266.  
  267.  
  268.  
  269. /*****************************************************************************/
  270.  
  271.  
  272.  
  273. /* Used to check for any unread required parameters. Returns true if we
  274. ** missed at least one. */
  275.  
  276. Boolean    MissedAnyParameters(AppleEvent *message)
  277. {
  278.     OSErr        err;
  279.     DescType    ignoredActualType;
  280.     AEKeyword    missedKeyword;
  281.     Size        ignoredActualSize;
  282.  
  283.     err = AEGetAttributePtr(    /* SEE IF PARAMETERS ARE ALL USED UP.          */
  284.         message,                /* AppleEvent to check.                          */
  285.         keyMissedKeywordAttr,    /* Look for unread parameters.                  */
  286.         typeWildCard,            /* So we can see what type we missed, if any. */
  287.         &ignoredActualType,        /* What it would have been if not coerced.      */
  288.         (Ptr)&missedKeyword,    /* Data area.  (Keyword not handled.)          */
  289.         sizeof(missedKeyword),    /* Size of data area.                          */
  290.         &ignoredActualSize        /* Actual data size.                          */
  291.     );
  292.  
  293. /* No error means that we found some unused parameters. */
  294.  
  295.     if (err == noErr)
  296.         err = errAEEventNotHandled;
  297.  
  298. /* errAEDescNotFound means that there are no more parameters.  If we get
  299. ** an error code other than that, flag it. */
  300.  
  301.     return(err != errAEDescNotFound);
  302. }
  303.  
  304.  
  305.  
  306. /*****************************************************************************/
  307.  
  308.  
  309.  
  310. void    NotifyCancel(void)
  311. {
  312.     if (gNotifyActive) {
  313.         NMRemove((NMRecPtr)&gNotifyUserInfo);
  314.         gNotifyActive = false;
  315.     }
  316. }
  317.  
  318.  
  319.  
  320. /*****************************************************************************/
  321.  
  322.  
  323.  
  324. void    NotifyUser(void)
  325. {
  326.     if (gNotifyUser) {
  327.         if (gInBackground) {
  328.             if (!gNotifyActive) {
  329.                 gNotifyUserInfo.nmIcon = GetResource('SICN', 128);
  330.                 NMInstall(&gNotifyUserInfo);
  331.                 gNotifyActive = true;
  332.             }
  333.         }
  334.     }
  335. }
  336.  
  337.  
  338.  
  339.